﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Collections;
using LinFu.Reflection;
using LinFu.DynamicProxy;

namespace ObjectBakery.Adapters.Strategies
{
    public class DataTableToListAdapter<T> : DataTableToListAdapter
    {
        public DataTableToListAdapter(DataTable table): base(table, typeof(T)){}
    }
    
    public class DataTableToListAdapter: IAdapterStrategy<DataTable, IList>
    {
        Type typeIn = typeof(DataTable);
        Type typeOut = typeof(IList);

        Helpers.DataSyncHelper syncHelper = new ObjectBakery.Helpers.DataSyncHelper();

        private DataTable implementationObject = new DataTable();
        public DataTable ImplementationObject
        {
            get
            {
                return implementationObject;
            }
            set
            {
                implementationObject = value;
            }
        }

        //put in base
        Type type;

        public DataTableToListAdapter(DataTable table, Type type)
        {
            ImplementationObject = table;
            this.type = type;
        }

        public void Fill(IList list)
        {
            ImplementationObject.Rows.Cast<DataRow>().ToList().ForEach(row =>
            {
                var inst = Activator.CreateInstance(type);

                //DynamicObject dynamicObject = new DynamicObject();
                //var inst = dynamicObject.CreateDuck(type);

                syncHelper.Sync(row, inst);
                list.Add(inst);
            });
        }

    
        public void Flush(IList list)
        {
            if (list.Count > 0)
                syncHelper.EnsureStructure(list[0], ImplementationObject.NewRow());

            ImplementationObject.Rows.Clear(); //drain existing
            list.Cast<object>().ToList().ForEach(item =>
            {
                if (item.GetType() == type)
                {
                    var row = ImplementationObject.NewRow();
                    syncHelper.Sync(item, row);
                    ImplementationObject.Rows.Add(row);
                }
                else
                {
                    //should we throw an exception here?
                }
            });
        }

        
    }
}
